// File Name: flash_logic.c
// Author: kukukukuku~
// Date: 2024-07-12

#include "./User/Flash/inc/flash_logic.h"
#include "./User/Key/inc/key_ctrl.h"
#include "./User/LED/inc/led_ctrl.h"
#include "./User/OLED/inc/oled_ctrl.h"
#include "./User/RS485/inc/rs485_ctrl.h"
#include "./User/Step_Motor/inc/step_motor_ctrl.h"
#include "./User/WS2812B/inc/ws2812b_ctrl.h"
#include "string.h"

/**
 * @brief   保存数据
 * @param   flashAddrStart: 起始地址
 * @param   data:           数据源
 * @param   dataLen:        数据个数
 * @retval  保存结果
 * - 0:     保存成功
 * - 1:     擦除失败
 * - 2:     保存失败
 * @note    None
*/
uint8_t flash_data_save(const uint32_t flashAddrStart, const uint16_t * const data, uint16_t dataLen)
{
    flash_unlock();
    if(flash_erase_sectors(FLASH_ADDR_DATA_START))
    {
        flash_lock();
        return 1;
    }
    
    //保存前缀
    if(flash_program_data_halfword(flashAddrStart, 0x1112))
    {
        flash_lock();
        return 2;
    }
    
    //保存数据个数
    if(flash_program_data_halfword(flashAddrStart + 2, dataLen))
    {
        flash_lock();
        return 2;
    }
    
    //保存数据
    for(uint8_t i = 0; i < dataLen; i++)
    {
        if(flash_program_data_halfword(flashAddrStart + (i + 2) * 2, data[i]))
        {
            flash_lock();
            return 2;
        }
    }
    
    flash_lock();
    return 0;
}


/**
 * @brief   读取数据
 * @param   None
 * @retval  读取结果
 * - 0:     读取成功
 * - 1:     读取失败
 * @note    None
*/
uint8_t flash_read(void)
{
    uint8_t i = 0;
    
    if(*(volatile uint16_t *)FLASH_ADDR_DATA_START == 0x1112 && *(volatile uint16_t *)(FLASH_ADDR_DATA_START + 2) == FLASH_DATA_NUM)
    {
        memcpy(flashData, (uint16_t *)(FLASH_ADDR_DATA_START + 4), sizeof(flashData));
        
        keyClickBeep                = flashData[FLASH_DATA_KEY_CLICK_BEEP_INDEX];
        keyLongBeep                 = flashData[FLASH_DATA_KEY_LONG_BEEP_INDEX];
        led1.mode                   = (uint8_t)flashData[FLASH_DATA_LED1_MODE_INDEX];
        led1.blinkNum               = flashData[FLASH_DATA_LED1_BLINK_FREQ_INDEX];
        led1.breathStep             = flashData[FLASH_DATA_LED1_BREATH_STEP_INDEX];
        led2.mode                   = (uint8_t)flashData[FLASH_DATA_LED2_MODE_INDEX];
        led2.blinkNum               = flashData[FLASH_DATA_LED2_BLINK_FREQ_INDEX];
        led2.breathStep             = flashData[FLASH_DATA_LED2_BREATH_STEP_INDEX];
        led1Switch                  = flashData[FLASH_DATA_LED1_SWITCH];
        led2Switch                  = flashData[FLASH_DATA_LED2_SWITCH];
        oledDir                     = (uint8_t)flashData[FLASH_DATA_OLED_DIR_INDEX];
        oledLightLevel              = (uint8_t)flashData[FLASH_DATA_OLED_LIGHT_INDEX];
        oledCursorStyle             = (uint8_t)flashData[FLASH_DATA_OLED_CURSOR_INDEX];
        oledMainPageRefreshInterval = flashData[FLASH_DATA_OLED_REFRESH_MS_INDEX];
        oledMenuNumberFlag          = (uint8_t)flashData[FLASH_DATA_OLED_MENU_NUMBER_INDEX];
        stepMotorMode               = (StepMotorMode)flashData[FLASH_DATA_STEP_MOTOR_MODE_INDEX];
        stepMotorSpd                = (uint8_t)flashData[FLASH_DATA_STEP_MOTOR_SPEED_INDEX];
        ws2812bMode                 = (uint8_t)flashData[FLASH_DATA_WS2812B_MODE_INDEX];
        ws2812bStopRed              = (uint8_t)flashData[FLASH_DATA_WS2812B_STOP_R_INDEX];
        ws2812bStopGreen            = (uint8_t)flashData[FLASH_DATA_WS2812B_STOP_G_INDEX];
        ws2812bStopBlue             = (uint8_t)flashData[FLASH_DATA_WS2812B_STOP_B_INDEX];
        ws2812bCwMode               = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_MODE_INDEX];
        ws2812bCwRed                = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_R_INDEX];
        ws2812bCwGreen              = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_G_INDEX];
        ws2812bCwBlue               = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_B_INDEX];
        ws2812bCcwMode              = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_MODE_INDEX];
        ws2812bCcwRed               = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_R_INDEX];
        ws2812bCcwGreen             = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_G_INDEX];
        ws2812bCcwBlue              = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_B_INDEX];
        rs485Mode                   = (uint8_t)flashData[FLASH_DATA_RS485_MODE];
        rs485Id                     = (uint8_t)flashData[FLASH_DATA_RS485_ID];
        rs485UsartBaudRate          = flashData[FLASH_DATA_RS485_BAUDRATE_H] << 16 | flashData[FLASH_DATA_RS485_BAUDRATE_L];
        rs485ActiveInterval         = flashData[FLASH_DATA_RS485_ACTIVE_INTERVAL_INDEX];
        versionMain                 = (uint8_t)(flashData[FLASH_DATA_VERSION_H] & 0xFF);
        versionSecond               = (uint8_t)(flashData[FLASH_DATA_VERSION_L] >> 8 & 0xFF);
        versionPhase                = (uint8_t)(flashData[FLASH_DATA_VERSION_L] & 0xFF);
        
        for(i = 0; i < sizeof(rs485UsartBaudRateList) / sizeof(rs485UsartBaudRateList[0]); i++)
        {
            if(rs485UsartBaudRate == rs485UsartBaudRateList[i])
            {
                break;
            }
        }
        
        if(i == sizeof(rs485UsartBaudRateList) / sizeof(rs485UsartBaudRateList[0]))
        {
            rs485UsartBaudRate = 115200;
        }
        
        oledMenuNumberFlagLast = oledMenuNumberFlag;
        rs485UsartBaudRateNew = rs485UsartBaudRate;
        
        return 0;
    }
    
    return 1;
}
